/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import socket from '@ohos.net.socket';
import wifi from '@ohos.wifi';
import { Configuration } from '../config/Configuration'
import { LoggerContext } from '../slf4j/LoggerContext';
import { Appender } from '../Appender'
import { Level } from '../Level';

var tcp = socket.constructTCPSocketInstance();

export class SMTPAppender {
    private fromMail: string
    private toMail: string
    private subject: string
    private smtpHost: string
    private smtpPort: number
    private username: string
    private password: string
    private OUT_TIME = 6000

    bind(loggerContext: LoggerContext, configure: Configuration) {
        for (var i = 0; i < configure.logger.length; i++) {
            if (loggerContext.getLoggerName() == configure.logger[i].name) {
                this.fromMail = configure.appender[i].fromMail
                this.toMail = configure.appender[i].toMail
                this.subject = configure.appender[i].subject
                this.smtpHost = configure.appender[i].smtpHost
                this.smtpPort = configure.appender[i].smtpPort
                this.username = configure.appender[i].username
                this.password = configure.appender[i].password
            }
        }
        for (var i = 0; i < configure.appender.length; i++) {
            if (configure.appender[i].className == Appender.SMTP) {
                let ipInfo = wifi.getIpInfo()
                let ip = this.intToIP(ipInfo.ipAddress)
                let promise = tcp.bind({ address: ip, port: 0, family: 1 });
                promise.then(() => {
                    tcp.connect({
                        address: { address: this.smtpHost, port: this.smtpPort },
                        timeout: this.OUT_TIME
                    }, err => {
                        if (err) {
                            console.error('connect tcp fail ' + JSON.stringify(err));
                            return;
                        }
                        console.info('connect tcp success')
                    })
                }).catch(err => {
                    console.error('bind tcp fail ' + JSON.stringify(err));
                });
            }
        }
    }

    async start(level: Level, msg: string) {
        await tcp.send({
            data: "AUTH LOGIN\r\n" + //发送登陆命令
            this.username + "\r\n" + //发送用户名的base64编码
            this.password + "\r\n" + //发送密码的base64编码
            "MAIL FROM: <" + this.fromMail + ">\r\n" + //发送用户名
            "RCPT TO: <" + this.toMail + ">\r\n", //发送收件人地址
            encoding: "UTF-8"
        })
        await tcp.send({
            data: "DATA\r\n", //发送数据命令
            encoding: "UTF-8"
        })
        await tcp.send({
            data: "From:" + this.fromMail + "\r\n" //发件人，要和前面的一致
            + "To:" + this.toMail + "\r\n" //收件人，要和前面的一致
            + "Subject:" + this.subject + "\r\n\r\n",
            encoding: "UTF-8"
        })
        await tcp.send({
            data: "\r\t" + level.getLevelStr() + ' ' + msg, //邮件正文内容
            encoding: "UTF-8"
        })
        await tcp.send({
            data: "\r\n.\r\n", //结束标志
            encoding: "UTF-8"
        })
        await tcp.send({
            data: "QUIT\r\n", //退出登录
            encoding: "UTF-8"
        })
        tcp.close()
    }

    intToIP(num) {
        var str;
        var tt = new Array();
        tt[0] = (num >>> 24) >>> 0;
        tt[1] = ((num << 8) >>> 24) >>> 0;
        tt[2] = (num << 16) >>> 24;
        tt[3] = (num << 24) >>> 24;
        str = String(tt[0]) + "." + String(tt[1]) + "." + String(tt[2]) + "." + String(tt[3]);
        return str;
    }
}